package com.ba.base.view.web

import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Build
import android.util.AttributeSet
import android.util.Log
import android.view.KeyEvent
import android.view.View
import android.view.ViewGroup
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.Observer
import com.ba.base.view.ILifecycle
import com.screx.mcloud.lib.view.web.WebViewClient
import com.tencent.smtt.sdk.WebSettings
import com.tencent.smtt.sdk.WebView
import qsos.core.lib.utils.file.FileUtils
import qsos.lib.base.callback.OnTListener

@SuppressLint("SetJavaScriptEnabled", "JavascriptInterface")
class H5VideoWebView : WebView, ILifecycle {

    private var mActivity: AppCompatActivity

    var mH5WebChromeClient: H5WebChromeClient? = null
    var mStatusLiveData: MutableLiveData<Int>? = null
    var mHeightData: MutableLiveData<Int> = MutableLiveData()
    var mLifeState: Int = 0

    constructor(context: Context) : super(context) {
        require(context is AppCompatActivity) { "context must be AppCompatActivity" }
        mActivity = context
        initWebView()
    }

    constructor(context: Context, attrs: AttributeSet?) : super(
        context,
        attrs
    ) {
        require(context is AppCompatActivity) { "context must be AppCompatActivity" }
        mActivity = context
        initWebView()
    }

    constructor(
        context: Context,
        attrs: AttributeSet?,
        defStyleAttr: Int
    ) : super(context, attrs, defStyleAttr) {
        require(context is AppCompatActivity) { "context must be AppCompatActivity" }
        mActivity = context
        initWebView()
    }

    private fun initWebView() {
        mActivity.lifecycle.addObserver(this)

        mStatusLiveData = MutableLiveData()
        mStatusLiveData?.value = 0

        settings.run {
            //设置渲染级别
            setRenderPriority(WebSettings.RenderPriority.HIGH)
            //数据库缓存
            databaseEnabled = true
            val cachePath = String.format("%s/%s", FileUtils.CACHE_PATH, "cacheDir")
            databasePath = cachePath
            //关闭硬件加速
           setLayerType(View.LAYER_TYPE_NONE, null);
            // 启动应用缓存
            setAppCacheEnabled(true)
            //Application Cache 缓存机制
            //以文件为单位进行缓存，且文件有一定更新机制（类似于浏览器缓存机制）
            //专门为 Web App离线使用而开发的缓存机制
            //存储静态文件（如JS、CSS、字体文件）
            setAppCachePath(cachePath)

            //设置支持缩放
            setSupportZoom(false)
            // 保存表单数据
            saveFormData = false
            // 缓存模式说明:
            // LOAD_CACHE_ONLY: 不使用网络，只读取本地缓存数据
            // LOAD_NO_CACHE: 不使用缓存，只从网络获取数据.
            // LOAD_DEFAULT: （默认）根据cache-control决定是否从网络上取数据。
            // LOAD_CACHE_ELSE_NETWORK，只要本地有，无论是否过期，或者no-cache，都使用缓存中的数据。
            cacheMode = WebSettings.LOAD_CACHE_ELSE_NETWORK
            // 排版适应屏幕
            layoutAlgorithm = WebSettings.LayoutAlgorithm.NORMAL
            //设置支持根据用户手势播放媒体,API17以上支持
            mediaPlaybackRequiresUserGesture = true
            //设置显示缩放控件,与setBuiltInZoomControls配合使用
            displayZoomControls = false
            //设置支持文件访问
            allowFileAccess = true
            //设置支持内容URL访问
            allowContentAccess = true
            //设置内容根据屏幕宽度适配
            loadWithOverviewMode = true
            //设置字体缩放百分比，设置为100时字体大小不会随系统字体改变而改变
//            textZoom = 100
            //设置支持meta标签，用于调整布局宽度
            useWideViewPort = true
            //设置支持多窗口
            setSupportMultipleWindows(true)
            //设置允许加载图片
            loadsImagesAutomatically = true
            //设置允许加载网络图片
            blockNetworkImage = false
            //设置允许加载网络资源
            blockNetworkLoads = false
            //设置允许JavaScript
            javaScriptEnabled = true
            //设置支持插件
            pluginState = WebSettings.PluginState.ON
            //设置支持DOM缓存
            domStorageEnabled = true
            //设置支持定位，需要定位权限
            setGeolocationEnabled(true)
            //设置内容混合模式，API21以上支持
            builtInZoomControls = true
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                mixedContentMode = 0
            }
        }

        //不缩放
        setInitialScale(80)
        // 与js交互
        addJavascriptInterface(WebJSInterface(mActivity, mHeightData), "android")
        // 硬件加速
//        setLayerType(View.LAYER_TYPE_HARDWARE, null)

        mH5WebChromeClient = H5WebChromeClient(mActivity, this)
        webChromeClient = mH5WebChromeClient
        webViewClient = WebViewClient(mActivity, object : OnTListener<Int> {
            override fun back(t: Int) {
                mStatusLiveData?.value = t
            }

        })

        setDownloadListener { url, _, _, _, _ ->
            val intent = Intent(Intent.ACTION_VIEW)
            intent.addCategory(Intent.CATEGORY_BROWSABLE)
            intent.data = Uri.parse(url)
            mActivity.startActivity(intent)
        }

        mHeightData.observe(mActivity, Observer {
        })

        viewTreeObserver.addOnDrawListener {
//            val param = layoutParams
//            param?.height = contentHeight
//            layoutParams = param
        }
    }

    override fun onKeyUp(keyCode: Int, event: KeyEvent): Boolean {
        return when (keyCode) {
            KeyEvent.KEYCODE_BACK -> {
                /** 回退键 事件处理 优先级:视频播放全屏-网页回退-关闭页面  */
                when {
                    mH5WebChromeClient?.mCustomView != null -> {
                        mH5WebChromeClient?.hideCustomView()
                    }
                    canGoBack() -> {
                        goBack()
                    }
                    else -> {
                        mActivity.finish()
                    }
                }
                true
            }
            else -> super.onKeyUp(keyCode, event)
        }
    }

    override fun onCreateLifecycle() {
        if (mLifeState != 0) {
            mLifeState = 0
            this.loadUrl("javascript: android_web_life('create')")
            Log.d("H5VideoWebView", "javascript: android_web_life('create')")
        }
    }

    override fun onResumeLifecycle() {
        if (mLifeState != 1) {
            mLifeState = 1
            onResume()
            resumeTimers()
            this.loadUrl("javascript: android_web_life('resume')")
            Log.d("H5VideoWebView", "javascript: android_web_life('resume')")
        }
    }

    override fun onPauseLifecycle() {
        if (mLifeState != 2) {
            mLifeState = 2
            onPause()
            this.loadUrl("javascript: android_web_life('pause')")
            Log.d("H5VideoWebView", "javascript: android_web_life('pause')")
        }
    }

    override fun onDestroyLifecycle() {
        if (mLifeState != 3) {
            mLifeState = 3
            this.loadUrl("javascript: android_web_life('destroy')")
            val parent = parent as ViewGroup?
            parent?.removeView(this)
            removeAllViews()
            loadDataWithBaseURL(null, "", "text/html", "utf-8", null)
            stopLoading()
            webChromeClient = null
            webViewClient = null
            mH5WebChromeClient = null
            destroy()
            Log.d("H5VideoWebView", "javascript: android_web_life('destroy')")
        }
    }

    override fun onChangedLifecycle() {

    }
}